perm filename SHADOW[901,BGB] blob
sn#129627 filedate 1974-11-12 generic text, type T, neo UTF8
00100 TITLE TEST
00200 EXTERNAL PASS3,occult,PASS5,PASS6,NUMTRI,TRITAB
00210
00300 INTERNAL STOP,GO,PATCH
00400 GO: JUMP
00500 JSR PASS3
00600 JSR occult
00700 JSR PASS5
00800 JSR PASS6
00900 STOP: HALT
00940 PATCH:
01000 BLOCK 100
01100 END GO
00100 TITLE PASS3
00200 EXTERNAL TRIBLKS,TRITAB,INPUT3,NUMTRI
00300 INTERNAL PASS3
00400 PASS3: 0
00500 SETZM NLEAST# ;COUNT OF TRIANGLES
00600 OPDEF OUTSTG [XWD 051140,0]
00700 ;ACCUMULATORS
00800 A←←XY1←←KA←←0
00900 B←←XY2←←AC0←←LA←←1
01000 C←←XY3←←AC1←←2
01100 AA←←I1←←Z12←←LO←←LB←←KB←←3
01200 BB←←I2←←Z3I←←HI←←4
01300 CC←←I3←←C12←←MID←←5
01400 X1←←AB1←←6
01500 X2←←AB2←←7
01600 X3←←AB3←←10
01700 Y1←←AB←←11
01800 Y2←←CC3←←12
01900 Y3←←13
02000 Z1←←Z←←14
02100 Z2←←TRI←←15
02200 Z3←←LC←←16
02300 ZT←←QB←←II←←KK←←KC←←17
02400 KPLANE←1
00100 LOOP: MOVE QB,NLEAST ;DONE YET
00200 CAML QB,NUMTRI
00300 JRST @PASS3
00400 ;BLIT TRIANGLE BLOCK INTO AC'S
00500 IMULI QB,5
00600 ADDI QB,INPUT3
00700 MOVSS QB
00800 BLT QB,4
00900 ;UNPACK TRIANGLE BLOCK
01000 FOR @$ I←1,3 {
01100 HLRE X$I,XY$I
01200 HRRE Y$I,XY$I ⎇
01300 HLRE Z1,Z12
01400 HRRE Z2,Z12
01500 HLRE Z3,Z3I
01600 HRRZ II,Z3I
01700 P3B:
01800 TRNE II,4 ↔ SKIPA I1,[1] ↔ SETZ I1,
01900 TRNE II,2 ↔ SKIPA I2,[1] ↔ SETZ I2,
02000 TRNE II,1 ↔ SKIPA I3,[1] ↔ SETZ I3,
02100 P3A:
02200 ;ORDER Z1 LEAST, Z3 MOST.
02300 DEFINE SWAP $ (N,M) {
02400 CAMG Z$N,Z$M
02500 JRST .+5
02600 EXCH X$N,X$M
02700 EXCH Y$N,Y$M
02800 EXCH Z$N,Z$M
02900 EXCH I$N,I$M ⎇
03000 SWAP 1,2
03100 SWAP 2,3
03200 SWAP 1,2
03300
03400 MOVE II,I1 ;RE-PACK I-BITS
03500 LSH II,1
03600 IOR II,I2
03700 LSH II,1
03800 IOR II,I3
03900
04000 EXCH II,[KPLANE]
00100 ;CALCULATE COEFFICIENTS OF THE PLANE OF THE TRIANGLE BY KRAMER'S RULE.
00200 DEFINE DET2B2 (A00,B11,B12,B21,B22) {
00300 MOVE B,B11
00400 MOVE C,B12
00500 IMUL B,B22
00600 IMUL C,B21
00700 SUB B,C
00800 IMUL B,A00 ⎇
00900
01000 DEFINE DETERM (A11,A12,A13,A21,A22,A23,A31,A32,A33) {
01100 DET2B2 A11,A22,A23,A32,A33
01200 MOVE A,B
01300 DET2B2 A12,A21,A23,A31,A33
01400 SUB A,B
01500 DET2B2 A13,A21,A22,A31,A32
01600 ADD A,B ⎇
01700
01800 DETERM KK,Y1,Z1,KK,Y2,Z2,KK,Y3,Z3
01900 MOVE AA,A
02000 DETERM X1,KK,Z1,X2,KK,Z2,X3,KK,Z3
02100 MOVE BB,A
02200 DETERM X1,Y1,KK,X2,Y2,KK,X3,Y3,KK
02300 MOVE CC,A
02400 DETERM X1,Y1,Z1,X2,Y2,Z2,X3,Y3,Z3
02500 MOVEM A,KSAVE#
02600 BRK:
03350 ;HALFWORD OVERFLOW.
03500 DEFINE HALFOV (W,WW){
03600 MOVM W,WW
03700 CAIGE W,400000
03800 JRST .+10
03900 MOVE W,KSAVE ;OVERFLOW
03910 ASH W,-1
03920 MOVEM W,KSAVE
03930 ASH AA,-1
03940 ASH BB,-1
03950 ASH CC,-1
04350 JRST .-11
04400 ⎇
04500 HALFOV A,AA
04600 HALFOV B,BB
04700 HALFOV C,CC
04800 P3C:
04900 ;PACK PLANE COEFFICIENTS
05000 HRL BB,AA
05100 HRLS CC
05200 EXCH KK,[KPLANE] ;COL-1
00100 ;CALCULATE LINE COEFFICIENTS
00200 DEFINE LINCOE (X1,X2,Y1,Y2,TA,TB,TC,X3,Y3) {
00300 MOVE TA,Y2
00400 MOVE TB,X1
00500 SUB TA,Y1 ;(Y2-Y1)=a
00600 SUB TB,X2 ;(X1-X2)=b
00700 HRL TC,TA
00800 HRR TC,TB
00900 IMUL TA,X1 ; A*x1
01000 IMUL TB,Y1 ; B*y1
01100 ADD TA,TB
01200 MOVNS TA
01300 MOVM TB,TA
01400 CAIGE TB,400000
01500 JRST .+6
01600 HLRE TA,TC ;HALFWORD OVERFLOW CURE
01700 HRRE TB,TC
01800 ASH TA,-1
01900 ASH TB,-1
02000 JRST .-15 ;JUMP TO THE "HRL" ABOVE.
02100 ;TA c
02200 ;TB free
02300 ;TC a,,b
02400 ;observe qqq sign convention - odd vertex positive.
02500 HLRE TB,TC
02600 IMUL TB,X3
02700 MOVEM TB,AC20
02800 HRRE TB,TC
02900 IMUL TB,Y3
03000 ADD TB,AC20
03100 ADD TB,TA
03200 JUMPGE TB,.+7
03300 MOVNS TA ;FLIP SIGN OF LINE COEFFICIENTS.
03400 HLRE TB,TC
03500 HRRE TC,TC
03600 MOVNS TB
03700 MOVNS TC
03800 HRL TC,TB
03900 ⎇
04000 HRL QB,Z3
04100 LINCOE X1,X2,Y1,Y2,A,B,C,X3,Y3
04200 LINCOE X1,X3,Y1,Y3,LA,LB,LC,X2,Y2 ;COL-2
04300 HRR CC,A ;PACK c3
04400 MOVEM KC,SAVKC#
04500 LINCOE X2,X3,Y2,Y3,KA,KB,KC,X1,Y1 ;COL-4
04600 HRL Y1,X1
04700 MOVE X1,KC
04800 MOVE KC,SAVKC
00100 P3D:
00200 ;PACK EVERYTHING INTO YOUR OLD KIT BAG AND SMILE SMILE SMILE
00300 ; WOULD YOU BELIEVE A LONG TRIANGLE BLOCK
00400 HRL Y2,X2
00500 HRL Y3,X3
00600 MOVE AB2,LC
00700 MOVE AB3,C
00800 MOVE 2,13
00900 HRL 1,0
01000 HRL 3,14
01100 HRR 3,15
01200 MOVE 0,11
01300 EXCH 1,12
01400 EXCH 5,12
01500 MOVE 11,4
01600 MOVE 4,17
01700 MOVE 13,KSAVE
01800
01900 ;BLIT BLOCK INTO LONG BLOCK TABLE.
02000 MOVE 17,NLEAST
02100 IMULI 17,14
02200 ADDI 17,TRIBLKS
02300 MOVE 16,17
02400 ADDI 16,13
02500 BLT 17,@16
00100 P3E:
00200 ;PUT TRIANGLE BLOCK POINTER INTO THE TRIANGLE TABLE
00300 ;IN ORDER ON MINIMUM DEPTH.
00400 HRL ZT,Z
00500 MOVE TRI,NUMTRI
00600 SKIPN LO,NLEAST
00700 JRST [AOS NLEAST ;FIRST TIME ONLY.
00800 MOVEM ZT,TRITAB-1(TRI)
00900 JRST LOOP]
01000 SETZ HI,
01100 PUT1: MOVE MID,LO ;MID:=(LO+HI+1)/2
01200 ADD MID,HI
01300 AOS MID
01400 ASH MID,-1
01500 MOVE LC,TRI ;FETCH Z(MID)
01600 SUB LC,MID
01700 HLRE A,TRITAB(LC)
01800 CAML Z,A
01900 JRST [CAMN LO,MID
02000 JRST PUT2
02100 CAMN HI,MID
02200 JRST PUT2
02300 MOVE LO,MID
02400 JRST PUT1]
02500 CAMN LO,MID
02600 JRST [AOS MID
02700 JRST PUT2]
02800 CAMN HI,LO
02900 JRST [AOS MID
03000 JRST PUT2]
03100 MOVE HI,MID
03200 JRST PUT1
03400 ;MOVE THE LOWER PART OF THE TRIANGLE TABLE,
03500 ;BETWEEN NLEAST AND MID,
03600 ;DOWN CORE BY ONE WORD.
03800 PUT2: CAMLE MID,NLEAST
03900 JRST PUT3
04000 MOVEI AC0,TRITAB
04100 ADD AC0,TRI
04200 MOVE AC1,AC0
04300 SUB AC0,NLEAST
04400 HRLS AC0
04500 SOS AC0
04600 SUB AC1,MID
04700 SOS AC1
04800 BLT AC0,@AC1
04900 PUT3: AOS NLEAST
05000 SUB TRI,MID
05100 MOVEM ZT,TRITAB(TRI)
05200 JRST LOOP
05300 AC20: 0
05400 END
00100 TITLE OCCULT
00200 EXTERNAL NUMTRI,OUTPDL,TRITAB,ENDPDL
00300 INTERNAL OCCULT
00400 OPDEF OUTSTR[XWD 5114,0]
00500 ;USE AND ABUSE OF ACCUMULATORS
00600 AC0←←0
00700 AC1←←1
00800 XM←←0
00900 YM←←1
01000
01100 XL←2 ;The window.
01200 XH←3
01300 YL←4
01400 YH←5
01500
01600 X1←AA←←6 ;The triangle.
01700 X2←BB←←7
01800 X3←CC←←10
01900
02000 Y1←MINZ←←11
02100 Y2←MAXZ←←12
02200 Y3←13
02300
02400 AB←←14 ;Plane coefficients.
02500 C←←15
02600
02700 T←16
02800 TT←17
03000
03100 XO←←14
03200 YO←←15
03300 PB←←17
03400
03500 ODD←←13
03600 NEW←←14
03700 OLD←←15
03800
03900 XY←←11
04000 X←←6
04100 Y←←7
04200 Z←←10
04300 EPTR←←14
04400 BPTR←←15
04500 CTB←←17
00100 ;O.O.R. - Occult Object Remover.
00200 OCCULT: 0
00300 hrl TT,numtri ;Triangle pointer.
00400 movns TT ;This op covertly Subtracts one from left half.
00500 hrri TT,tritab-1
00600 movem TT,triptr#
00700
00800 movni XL,1000 ;first window
00900 movei XH,1000
01000 movni YL,1000
01100 movei YH,1000
01200 FOR W IN (PENOLD,PENNEW,SUR,SUR3,APEN,ASUR,ASUR3){
01300 SETZM W}
01400 movei 377777
01500 movem ZH#
01600 movei sqrpdl+1
01700 movem sqrpdl
01800 movei outpdl+1
01900 movem outpdl
02000 jrst .V
02100 ;Occult Window Loop.
02200 OWLOOP: sos 1,sqrpdl
02300 caig 1,sqrpdl+1
02400 jrst @occult ;no more windows.
02500
02600 hlre XL,-5(1) ;new window
02700 hrre XH,-5(1)
02800 hlre YL,-4(1)
02900 hrre YH,-4(1)
03000
03100 hrre -3(1) ;back limit.
03200 movem ZH
03300
03400 move (1) ;triangle pointer
03500 movem triptr
03600
03700 move -2(1) ;ancesters
03800 movem apen#
03900 move -1(1)
04000 movem asur#
04100 hlrz -3(1)
04200 movem asur3#
04300
04400 setzm pennew# ;descendants
04500 setzm penold#
04600 setzm sur#
04700 setzm sur3#
04800
04900 subi 1,5
05000 movem 1,sqrpdl
05100 jrst .V
00100 ;Virgin - scan for first triangle.
00200 .V: jsr pns
00300 jrst [ movem minz,penzlo#
00400 movem maxz,penzhi#
00500 movem T,pennew
00600 jrst .P]
00700 jrst owloop
00800 movem minz,surzlo#
00900 movem maxz,surzhi#
01000 hrlzm T,sur
01200 ;One surrounder.
01300 .S: jsr pns
01400 jrst [ caml minz,surzhi
01500 jrst .S ;B - penetrator is behind surrounder.
01600 movem T,pennew
01700 caml maxz,surzlo
01800 jrst %PS ;C - penetrator and surrounder conflict.
01900 movem minz,penzlo ;F - penetrator is in Front of surrounder
02000 movem maxz,penzhi
02100 jrst .SP]
02200 jrst alpha ;DISPLAY a surrounder.
02300 caml minz,surzhi
02400 jrst .S ;B - new surrounder is behind old surrounder.
02500 caml maxz,surzlo
02600 jrst [ movem minz,zlo# ;C - surrounders conflict.
02700 movem maxz,zhi#
02800 hrrm T,sur
02900 jrst .SS]
03000 movem minz,surzlo ;F - new surrounder is in front of old surrounder
03100 movem maxz,surzhi
03200 hrlm T,sur
03300 jrst .S
03400
03500 ;One Penetrator.
03600 .P: jsr pns
03700 jrst [movem T,penold
03800 camle minz,penzhi
03900 jrst %PP ;B
04000 caml maxz,penzlo
04100 jrst .PP ;C
04200 jrst %PP] ;F
04300
04400 jrst beta ;DISPLAY penetrator.
04500
04600 movem minz,surzlo
04700 movem maxz,surzhi
04800 hrlzm T,sur
04900 caml minz,penzhi
05000 jrst .PS ;B
05100 caml maxz,penzlo
05200 jrst %PS ;C
05300 setzm pennew ;F
05400 jrst .S
05500
05600 ;Two surrounders.
05700 .SS: jsr pns
05800 jrst [ caml minz,surzhi
05900 jrst .SS ;B
06000 caml minz,zhi ;F & C
06100 jrst .SS ;b
06200 movem T,pennew ;f & c
06300 jrst %PSS]
06400 jrst gamma ;DISPLAY two penetrators.
06500
06600 caml minz,surzhi
06700 jrst .SS ;B
06800 caml maxz,surzlo
06900 jrst [ caml minz,zhi ;C
07000 jrst .SS ;b
07100 caml maxz,zlo
07200 jrst [ hrrzm T,sur3 ;c
07300 jrst %SSS]
07400 hrrm T,sur
07500 movem minz,zlo
07600 movem maxz,zhi
07700 jrst .SS]
07800 caml minz,zhi
07900 jrst .SS
08000 caml maxz,zlo
08100 jrst [ hrlm T,sur ;c
08200 movem minz,surzlo
08300 movem maxz,surzhi
08400 jrst .SS]
08500 hrlzm T,sur ;f
08600 movem minz,surzlo
08700 movem maxz,surzhi
08800 jrst .S
08900
00100 ;A surrounder behind a penetrator.
00200 .PS:
00300 .SP: jsr pns
00400 jrst [ caml minz,surzhi
00500 jrst .PS ;B
00600 movem T,penold
00700 caml maxz,surzlo
00800 jrst %PPS ;C
00900 camle minz,penzhi ;F
01000 jrst %PP ;b
01100 caml minz,penzlo
01200 jrst .PP ;c
01300 jrst %PP] ;f
01400
01500 jrst beta ;DISPLAY.
01600
01700 caml minz,surzhi
01800 jrst .PS ;B
01900 caml maxz,surzlo
02000 jrst [ hrrm T,sur ;C
02100 jrst %PSS]
02200 hrlm T,sur ;F
02300 movem minz,surzlo
02400 movem maxz,surzhi
02500 caml minz,penzhi
02600 jrst .PS ;B
02700 caml maxz,penzlo
02800 jrst %PS ;C
02900 setzm pennew ;F
03000 jrst .S
03100
03200
03300 SQRPDL: .+1 ;WINDOW SQUARE IN CORE PUSHDOWN LIST
03400 0 ; XL XH
03500 0 ; YL YH
03600 0 ;sur3,,ZH
03700 0 ; PEN1,,PEN2
03800 0 ; SUR1,,SUR2
03900 0 ; TRIPTR
04000 BITS←←=10 ;NUMBER OF BITS OF DISPLAY RASTER.
04100 BLOCK (BITS*3+1)*6
04200 SQREND:
04300 FACES←←12 ;CORNER PENETRATION DATA AREA
04400 CORPDL: .+1
04500 BLOCK FACES
04600 PENPDL: .+1
04700 BLOCK FACES
04800 CTBPTR: .+1
04900 BLOCK FACES*13
00100 ;Display output one-surrounder.
00200 ALPHA: HLRZ T,SUR
00350 MOVEM T,PENNEW
00400 ;DISPLAY OUTPUT ONE-PENETRATOR.
00500 BETA: MOVE AC0,XH
00600 SUB AC0,XL
00700 HRLM AC0,@OUTPDL
00800 MOVE AC1,PENNEW
00900 HRRM AC1,@OUTPDL
01000 AOS OUTPDL
01100 HRLM XL,@OUTPDL
01200 HRRM YL,@OUTPDL
01300 AOS OUTPDL
01400 JRST OWLOOP
01500
01600 ;DISPLAY OUTPUT TWO-SURROUNDERS
01700 GAMMA: MOVE AC0,XH
01800 SUB AC0,XL
01900 TRO AC0,400000
02000 HRLM AC0,@OUTPDL
02100 HLRZ 1,SUR
02200 HRRM AC1,@OUTPDL
02300 AOS OUTPDL
02400 HRLM XL,@OUTPDL
02500 HRRM YL,@OUTPDL
02600 AOS OUTPDL
02700 HRRZ 1,SUR
02800 HRRZM AC1,@OUTPDL
02900 AOS OUTPDL
03000 HLRZ SUR
03002 HRRZ 1,SUR
03004 MOVEM PENOLD
03006 MOVEM 1,PENNEW
03100 ;Display two penetrators.
03200 EPSILON:
03300 MOVE XH
03400 SUB XL
03500 HRLM @OUTPDL
03600 MOVE 1,PENOLD
03700 HRRM 1,@OUTPDL
03800 AOS OUTPDL
03900 HRLM XL,@OUTPDL
04000 HRRM YL,@OUTPDL
04100 AOS OUTPDL
04200 JRST BETA
00100 ;OCCUPATION VOLUME
00200
00300 ; Compute the occupation volume of the Triangle pointed
00400 ;to by T for the window XL XH YL YH, find the minimum and maximum Z for all
00500 ;corners of the window without exceeding the triangle's total volume z1
00600 ;minimum to z3 maximum; if you are worth anything you have by now realized
00700 ;that this will yield too large a volume for numerous penetrator cases
00800 ;where the vertices aren't in the window and the corners aren't in the triangle
00900 ;but it doesn't matter and will all come out correctly further along.
01000
01100 OCCVOL: 0
01200 HLRE AA,11(T) ;PICKUP COEFFICIENTS OF TRIANGLE'S PLANE.
01300 HRRE BB,11(T)
01400 HLRE CC,12(T)
01500 SETCM T
01600 TLNE (5B2) ;IF EXTREME VERTICES ARE WITHIN...
01700 JRST .+4
01800 HLRE MINZ,3(T) ;THEN OCCUPATION VOLUME IS OBVIOUS.
01900 HLRE MAXZ,4(T)
02000 JRST @OCCVOL
02100 HRLZI MAXZ,400000 ;Z1
02200 SETCAM MAXZ,MINZ ;Z3
02300 ;calculte z-depth of window corners in the plane of the triangle.
02400 FOR I←0,3
02500 {
02600 MOVE AC0,13(T)
02700 MOVE AC1,XL+(I∧1)
02800 IMUL AC1,AA
02900 SUB AC0,AC1
03000 MOVE AC1,YL+((I∧2)⊗-1)
03100 IMUL AC1,BB
03200 SUB AC0,AC1
03300 IDIV AC0,CC
03400 CAMGE AC0,MINZ
03500 MOVE MINZ,AC0
03600 CAMLE AC0,MAXZ
03700 MOVE MAXZ,AC0
03800 ⎇
03900 ;Clip window's projected volume to the extreme volume of the triangle.
04000 HLRE AC0,3(T)
04100 HLRE AC1,4(T)
04200 CAMLE AC0,MINZ
04300 MOVE MINZ,AC0
04400 CAMGE AC1,MAXZ
04500 MOVE MAXZ,AC1
04600
04700
04800 JRST @OCCVOL
00100 ;P.O.S. - Penetrator, Outsider, Surrounder.
00200 pos:
00300 comment/ POS determines the relationship between a triangle and a window
00400 and skips respectively. For penetrators it always calculates
00500 vertex-within-bits, For Pen & Surs it always calculates volume.
00600 Accumulators IN: XL,XH,YL,YH, & T(right half).
00700 /
00800
00900 ;GET TRIANGLE'S COORDINATES INTO ACCUMULATORS.
01000 define gettac {
01100 hlre x1,0(T)
01200 hlre x2,1(T)
01300 hlre x3,2(T)
01400 hrre y1,0(T)
01500 hrre y2,1(T)
01600 hrre y3,2(T)
01700 }
01800 gettac
01900
02000 ;If all the corners of the triangle are to one side of the window,
02100 ; then the triangle is Outside.
02200
02300 define Outside $ (M,N,P,HL) {
02400 CAM$M P$HL,P$1 ↔ JRST .+5
02500 CAM$M P$HL,P$2 ↔ JRST .+3
02600 CAM$N P$HL,P$3 ↔ JRST pnsout
02700 }
02800 Outside LE,g,X,H
02900 Outside LE,g,Y,H
03000 Outside GE,l,X,L
03100 Outside GE,l,Y,L
03200
03300
03400 ;If any vertex of the Triangle is within the window,
03500 ; then it is a penetrator.
03600 ;EDGE CASES.
03700 For @$ N←1,3 {
03800 caml X$N,XH ↔JRST[CAMN X$N,XH ↔ IOR T,[1⊗(=21-N)]↔ jrst .+7]
03900 caml XL,X$N ↔JRST[CAMN XL,X$N ↔ IOR T,[1⊗(=21-N)]↔ jrst .+5]
04000 caml Y$N,YH ↔JRST[CAMN Y$N,YH ↔ IOR T,[1⊗(=21-N)]↔ jrst .+3]
04100 camg YL,Y$N ↔JRST[CAMN YL,Y$N↔JRST[IOR T,[1⊗(=21-N)]↔JRST .+1]↔ ior T,[1⊗(=36-N)]↔JRST .+1]
04200 }
04300
04400 tlnn T,(7b2)
04500 jrst .+3
04600 jsr occvol ;Found a Penetrator.
04700 jrst @pns
04800
04900
00100 ;SURROUNDS
00200
00300 comment/ For each edge of the triangle, if for every corner of
00400 the window QQQ is the same sign then that edge does not pass
00500 thru the window. The odd vertex is in the opposite half plane
00600 from the window if the QQQs are all negative - which is
00700 equivalent to saying that the triangle is outside of the window.
00800 /
00900 jsr calq
01000 jrst pnsout ;OUTSIDE.
01100 tlne T,77770
01200 jrst [jsr occvol ↔ jrst @pns] ;PENETRATOR.
01300 jsr occvol ↔ camge maxz,zh ↔ movem maxz,zh ;lower ZH - SURROUNDER.
01400 aos pns
01500 aos pns
01600 jrst @pns
01700
01800 ;P.N.S - Penetrator, Nil list, Surrounder.
01900 pns: 0
02000 ;Get pointer to next triangle, if list is empty or triangle is
02100 ;beyond the back limit then take the NIL exit.
02200 pnsout: skipe T,asur ;Check for ancestors.
02300 jrst [hlrzs T ;left SUR 1.
02400 jumpe T,[exch T,asur ;right SUR 2
02500 jrst pnssur]
02600 hrrzs asur
02700 jrst pnssur]
02800 skipe T,asur3
02900 jrst [setzm asur3
03000 jrst pnssur]
03100 skipe T,apen
03200 jrst [hlrzs T ;left PEN 1
03300 jumpe T,[exch T,apen ;right pen 2
03400 jrst pos]
03500 hrrzs apen
03600 jrst pos]
03700 move TT,Triptr
03800 beyond: aobjp TT,[aos pns
03900 jrst @pns]
04000 movem TT,Triptr
04100 hrrz T,(TT)
04200 hlre (TT)
04300 caml zh
04400 jrst @beyond ;beyond ZH.
04500 jrst pos
04600 pnssur: jsr occvol ↔ camge maxz,zh ↔ movem maxz,zh ;lower Zh.
04700 aos pns ;surrounds
04800 aos pns
04900 jrst @pns
00100 ;Calculate QQQ-bits, skip if not outside.
00200 calq: 0
00300 movsi PB,40000 ;Select QQQ bit.
00400 define qqq (corner) {
00500 hlre ac1,AB
00600 hrre ac0,AB
00700 imul ac1,XL+ (corner ∧ 1)
00800 imul ac0,YL+((corner ∧ 2)⊗-1)
00900 add ac1,ac0
01000 add ac1,C
01100 }
01200
01300 for edge ← 1,3 {
01400 move AB,5+edge(T) ;Get line Coefficients
01500 IFE (edge-1),<hlre C,5(T)>
01600 IFE (edge-2),<hrre C,5(T)>
01700 IFE (edge-3),<hrre C,12(T)>
01800 for corner ← 0,3 {
01900 qqq corner
02000 skipge ac1 ;Q sign convention - odd vertex positive.
02100 ior T,PB
02200 rot PB,-1
02300 }
02400
02500 setcm ac1,T
02600 tlnn ac1,(17⊗(=33-edge*4))
02700 jrst @calq ;Triangle outside of window.
02800 }
02900 aos calq
03000 jrst @calq
00100 ;Convert QQQ-bits into Pen-bits.
00200 CONQQQ: 0
00300 gettac
00400 ;Accumulators IN: XL,XH,YL,YH (the window)
00500 ; X1,X2,X3,Y1,Y2,Y3 (the triangle)
00600 ; T (the triangle pointer)
00700 ;Accumulators clobbered 0,1,14,15.
00800 tlne T,(7B2) ;If a vertex is within, then we must calQ.
00900 jrst [ jsr calq
01000 jfcl
01100 jrst .+1]
01200 for @$ edge←1,3 {
01300 BP←←2+edge*4 ;Bit pointer for testing.
01400 V ←←((7-edge)*edge)/2 ;non-edge select bits.
01500 setcm T ;If both vertices within,
01600 tlne (V ⊗=33)
01700 jrst .+3
01800 tlz T,(17⊗(=35-BP)) ;Then zero NSEW byte.
01900 jrst conq$edge
02000
02100 ;Convert 4-bit byte by table lookup.
02200 ldb ac1,[point 4,T,BP]
02300 move [ 0 ↔ 12 ↔ 11 ↔ 3 ↔ 6 ↔ 14 ↔ 0 ↔ 5
02400 5 ↔ 0 ↔ 14 ↔ 6 ↔ 3 ↔ 11 ↔ 12 ↔ 0](ac1)
02500
02600 tlne T,(V ⊗ =33) ;If both vertices without
02700 jrst .+6
02800 dpb [point 4,T,BP]
02900 movei 1,V
03000 jsr skpcruz
03100 tlz T,(17⊗(=35-bp)) ;no crossings - zip NSEW.
03200 jrst conq$edge ;Then we are done, Else:
03300
03400 ;Find vertex that is outside the window.
03500 selec1←←(IFE(1-edge),<1+>0) ;1,0,0 - first select.
03600 selec2←←(IFE(3-edge),<1+>1) ;2,2,1 - second select.
03700 tlne T,(1⊗(=35-selec1))
03800 ;First selected bit is inside, hence second is outside.
03900 jrst [
04000 move XO,X1+selec2
04100 move YO,Y1+selec2
04200 jrst .+3]
04300
04400 ;First selected bit is outside.
04500 move XO,X1+selec1
04600 move YO,y1+selec1
04700
04800 ;Call one-crossing routine & you are done.
04900 jsr cross
05000 dpb [point 4,T,BP]
05100 conq$edge:
05200 }
05300 jrst @conqqq
00100 CROSS: 0
00200
00300 comment / The following tortured logic converts qqq-bits (which
00400 tell which half plane the window corners are in with respect
00500 to the lines determined by the triangle) into pen-bits (which
00600 tell which sides of the window: North, South, East or West, each
00700 triangle edge segment crosses).
00800
00900 Accumulators: XO,YO & AC1.
01000 /
01100
01200 ;If the 2-bit is on
01300 trne 2 ↔ jrst [
01400 ;then
01500
01600 ;If XO ≥ XH
01700 caml XO,XH ↔ jrst [
01800 ;Then 2-mask
01900 andi 2
02000 jrst @cross ]
02100 ;Else 15-mask
02200 andi 15
02300 jrst @cross ]
02400
02500 ;Else
02600 ;If 10-bit is on
02700 trne 10 ↔ jrst [
02800 ;Then If YO ≥ YH
02900 caml YO,YH ↔ jrst [
03000 ;Then 10-mask
03100 andi 10
03200 jrst @cross]
03300 ;Else 5-mask
03400 andi 5
03500 jrst @cross]
03600 ;Else If XL > XO
03700 camle XL,XO ↔ jrst [
03800 ;Then 1-mask
03900 andi 1
04000 jrst @cross]
04100 ;Else 4-mask
04200 andi 4
04300 jrst @cross
04400
04500 ;SKIPs if outsiders' edge crosses window. No crossings - no Skippings.
04600 skpcruz: 0
04700 setz
04800 for @$ i←1,3 {
04900 camle x$i,XL
05000 tro 1⊗(3-i)
05100 camle y$i,yl
05200 tro 1⊗(22-i)
05300 camle xh,x$i
05400 tlo 1⊗(3-i)
05500 camle yh,y$i
05600 tlo 1⊗(22-i)
05700 }
05800 tdnn 1 ↔ jrst @skpcruz
05900 tsnn 1 ↔ jrst @skpcruz
06000 rot 3
06100 tdnn 1 ↔ jrst @skpcruz
06200 tsnn 1 ↔ jrst @skpcruz
06300 aos skpcruz
06400 jrst @skpcruz
00100 ;Two Penetrators.
00200 ;Is an edge possible
00300 ;Do both pen have no vertices within
00400 .pp: move T,pennew
00500 tlne T,(7B2)
00600 jrst %PP
00700 move TT,penold
00800 tlne TT,(7B2)
00900 jrst %PP
01000 MOVEM MINZ,MINZZ#
01100 MOVEM MAXZ,MAXZZ#
01200
01300 ;Does ONLY ONE and the same edge intersect the window for each pen
01400 .PP1:
01500 define edgep $ (NNN) {
01600 jsr conqqq ;convert q-bits into pen-bits.
01700 movei 1
01800 movem en$nnn
01900 ldb [point 4,T,6]
02000 jumpn [ ldb 1,[point 8,T,14]
02100 jumpn 1,%PP
02200 jrst .+6]
02300 aos en$nnn
02400 ldb [point 4,T,10]
02500 jumpn [ldb 1,[point 4,t,14]
02600 jumpn 1,%PP
02700 jrst .+3]
02800 aos en$nnn
02900 ldb [point 4,T,14]
03000 movem ep$nnn
03100 movem T,IFE(nnn-1),<pennew> IFE(nnn-2),<penold>
03200 }
03300 edgep 1
03400 move T,penold
03500 edgep 2
03600 move TT,T
03700 move T,pennew
03800 came ep1
03900 jrst .+1 ;Penetration bits do not match.
00100 ;Are the edges' endpoints identical
00200 .PP2: move 1,en1 ;edge new's number.
00300 hrrz new,T ;pennew pointers
00400 hrl new,T
00500 hrrz old,TT ;penold pointers
00600 hrl old,TT
00700 add new,[0 ↔ xwd 1,2 ↔ xwd 0,2 ↔ xwd 0,1](1)
00800 move 1,en2
00900 add old,[0 ↔ xwd 1,2 ↔ xwd 0,2 ↔ xwd 0,1](1)
01000 move (new)
01100 came (old)
01200 jrst [movss old
01300 came (old)
01400 jrst %PP ;match failure
01500 jrst .+1]
01600 movss new
01700 movss old
01800 move (new)
01900 came (old)
02000 jrst %PP ;match failure.
02100
02200 ;Are odd vertices in opposite half planes
02300 .PP3:
02400 comment / Let's do this one by picking up pennew's
02500 line-coefficients and penold's odd-vertex and multiplying
02600 them together in order to look at Q's sign./
02700
02800 ;Get line coefficients for edge-pennew 1.
02900 move 1,en1
03000 xct [0
03100 hlre C,5(T)
03200 hrre C,5(T)
03300 hrre C,12(T)](1)
03400 add 1,T
03500 move AB,5(1)
03600
03700 ;Get odd-vertex for edge-penold 2; x y z.
03800 .PP4: move odd,en2
03900 xct [0
04000 hlre 3(TT)
04100 hrre 3(TT)
04200 hlre 4(TT)](odd)
04300 movem zodd# ;save odd z-depth value.
04400 add odd,TT
04500 move odd,-1(odd) ;odd's x,,y.
04600
00100 ;Calculate QQQ.
00200 .PP5: hlre ac1,AB
00300 hlre ac0,odd
00400 imul ac1,ac0 ; a*X + ...
00500 hrre ac0,AB
00600 hrre AB,odd
00700 imul ac0,AB ; b*Y + ...
00800 add ac1,ac0
00900 add ac1,C ; c = qqq
01000 jumpge ac1,EdOver ;Edge's penetrators overlap.
01100 ;Coplanar & No intensity turned on edge
01200 move 1,en1
01300 ldb ibpt(1)
01400 jumpn .PP7
01500 move 1,en2
01600 ldb ibptt(1)
01700 jumpn .PP7
01800 TLNE T,7 ;SPECIAL EDGE CASE.
01900 JRST .PP7
02000 ;COPLANAR TEST.
02100 HLRE 11(T)↔MUL 13(TT)↔HLRE 14,11(TT)↔MUL 14,13(T)↔CAME 14↔JRST .PP7↔CAME 1,15↔JRST .PP7
02200 HRRE 11(T)↔MUL 13(TT)↔HRRE 14,11(TT)↔MUL 14,13(T)↔CAME 14↔JRST .PP7↔CAME 1,15↔JRST .PP7
02300 HLRE 12(T)↔MUL 13(TT)↔HLRE 14,11(TT)↔MUL 14,13(T)↔CAME 14↔JRST .PP7↔CAME 1,15↔JRST .PP7
02400 ;Full Fledged Surrounder.
02500 move pennew
02600 hrlzm sur
02700 setzm pennew
02800 setzm penold
02900 move penzlo ↔ movem surzlo
03000 move penzhi ↔ movem surzhi
03100 camge ZH ↔ movem ZH
03200 jrst .S
00100 ;Final Edge Logic.
00200 .PP7: MOVE MINZ,MINZZ ↔ MOVE MAXZ,MAXZZ
00300 camge minz,penzlo ↔ movem minz,penzlo
00400 camle maxz,penzhi ↔ movem maxz,penzhi
00500 move penzhi ↔ camge zh ↔ movem zh
00600 ;pseudo-surrounder.
00700 move Triptr ;save pointer.
00800 movem Tpsav#
00900 .PP7a: jsr pns
01000 jrst .PP8
01100 jrst epsilon
01200 skipe sur ↔ jrst [hrrm T,sur ↔ jrst .PP8]
01300 hrlzm T,sur
01400 caml minz,penzhi
01500 jrst .PP7a ;B
01600 caml maxz,penzlo
01700 jrst .PP8 ;C
01800 setzm pennew ;F
01900 setzm penold
02000 movem minz,surzlo
02100 movem maxz,surzhi
02200 jrst .S
02300 ;Final Edge Failure.
02400 .PP8: move Tpsav
02500 movem Triptr
02600 jrst %PP
02700 ;Edge Parametes
02800 en1: 0 ;pennew's edge's number.
02900 en2: 0 ;penold's edge's number.
03000 ep1: 0 ;pennew's edge's pen-bits byte.
03100 ep2: 0 ;penold's edge's pen-bits byte.
03200 ;define intensity bit byte pointers.
03300 ibptt: 0
03400 point 1,4(TT),33
03500 point 1,4(TT),34
03600 point 1,4(TT),35
03700 ibpt: 0
03800 point 1,4(T),33
03900 point 1,4(T),34
04000 point 1,4(T),35
00100 ;The two edge penetrators overlap,
00200 ; that is the odd vertices are not in opposite halfplanes.
00300 EdOver: MOVE MINZ,MINZZ ↔ MOVE MAXZ,MAXZZ
00400 comment/ We shall determine which penetrator is hidden by finding
00500 out which is deeper from the window.
00600
00700 Accumulators IN: AA,BB,CC which contain the plane coefficients
00800 of pennew leftover from occvol.
00900 & ODD odd vertex of penold.
01000
01100 Also remember that AA*x + BB*y + CC*z = kplane.
01200 /
01300 HLRE AA,11(T)
01400 HRRE BB,11(T)
01500 HLRE CC,12(T)
01600 move ac0,13(T)
01700 hlre ac1,odd
01800 imul ac1,AA
01900 sub ac0,ac1
02000 hrre ac1,odd
02100 imul ac1,BB
02200 sub ac0,ac1
02300 idiv ac0,CC
02400 camge ac0,zodd
02500
02600
02700 jrst [
02800 ;Penold is hidden, Pennew is a single penetrator.
02900 setzm penold ↔ movem minz,penzlo ↔ movem maxz,penzhi
03000 move 1,en2
03100 ldb ibptt(1)
03200 jumpe .P
03300 move 1,en1
03400 dpb ibpt(1)
03500 JRST .P
03600 ]
03700
03800 ;Pennew is hidden, Penold is a single penetrator.
03900 move 1,en1
04000 ldb ibpt(1)
04100 jumpe .+3
04200 move 1,en2
04300 dpb ibptt(1)
04400 movem TT,pennew
04500 setzm penold
04600 jrst .P
00100 ;Save Father's surrounders & penetrators and EXIT.
00200 %SSS: ↔ %PSS: ↔ %PPS: ↔ %PP: ↔ %PS:
00300 move 11,ZH
00400 hrl 11,sur3
00500 move 12,penold
00600 hrl 12,pennew
00700 move 13,sur
00800 move 14,triptr
00900 ;Split up the window, Recursion Exit.
01000 rexit: move XM,XL
01100 move YM,YL
01200 add XM,XH
01300 add YM,YH
01400 ash XM,-1
01500 ash YM,-1
01600 camn XL,XM ;resolution
01700 jrst owloop
01800 camn XH,XM
01900 jrst owloop
02000 move 6,sqrpdl ;setup blit pointer
02100 hrli 6,7
02200 move 15,6
02300 move 16,6
02400 move 17,6
02500 addi 16,6
02600 addi 17,14
02700 move 7,XH ;lower-right-window
02800 move 10,YM
02900 hrl 7,XM
03000 hrl 10,YL
03100 blt 15,5(6)
03200 movss 7 ;lower-left-window
03300 hrl 7,XL
03400 blt 16,13(6)
03500 movss 10 ;upper-left-window
03600 hrr 10,YH
03700 blt 17,21(6)
03800 addi 6,22
03900 HRRZM 6,sqrpdl ;update pdl pointer.
04000 ;initialize OWL loop for upper-right window.
04100 move XL,XM
04200 move YL,YM
04300 movem 12,apen ;anscestors.
04400 movem 13,asur
04500 hlrzm 11,asur3
04600 setzm penold ;descendants.
04700 setzm pennew
04800 setzm sur
04900 setzm sur3
05000 jrst .V
05100 END
00100 TITLE PASS5
00200 EXTERNAL INPUT5,INPUT6,FFLAG,OUTPDL,END6
00300 INTERNAL PASS5
00400 ;ACCUMULATORS
00500 XL←←0
00600 YL←←1
00700 XH←←2
00800 YH←←3
00900 X1←←B←←KK←←4
01000 Y1←←KKK←←5
01100 X2←←CC←←6
01200 Y2←←CCC←←Q←←7
01300 XM←←AAA←←10
01400 YM←←BBB←←11
01500 XN←←AA←←12
01600 YN←←BB←←13
01700 X←←14
01800 Y←←15
01900 P←←16
02000 A←←17
00100 PASS5: 0
00200 MOVEI P,INPUT5-1
00300 MOVE A,OUTPDL
00400 SUBI A,INPUT5-1
00500 MOVNS A
00600 HRL P,A
00700 MOVEM P,TEM1#
00800 MOVEI P,INPUT6
00900 LOOP: HRRZ A,P
00905 SUBI A,END6
00910 SKIPL A
00915 JRST EXIT5 ;OUTPUT BUFFER OVERFLOW.
00920 EXCH P,TEM1
01000 AOBJP P,EXIT5
01100 MOVE A,(P)
01200 AOBJP P,EXIT5
01300 HLRE XL,(P)
01400 HRRE YL,(P)
01500 MOVE XH,XL
01600 MOVE YH,YL
01700 HLRZ X,A
01800 ANDI X,177777
01900 ADD XH,X
02000 ADD YH,X
02100
02200 EXCH P,TEM1
02300
02310 SKIPE FFLAG ;TEST FRAME FLAG
02320 JSR FRAME
02330
02400 TLNE A,600000
02500 JRST INTERS
02600
02700 HRL A,4(A) ;PENETRATOR
02800 DEFINE UNPACK (N,M) {
02900 MOVE Y1,N-1(A)
03000 MOVE Y2,M-1(A)
03100 HLRE X1,Y1
03200 HLRE X2,Y2
03300 HRRES Y1
03400 HRRES Y2
03500 JSR CLIP
03600 ⎇
03700 TLNE A,4
03800 JRST [UNPACK 2,3
03900 JRST .+1]
04000 TLNE A,2
04100 JRST [UNPACK 1,3
04200 JRST .+1]
04300 TLNE A,1
04400 JRST [UNPACK 1,2
04500 JRST .+1]
04600 JRST LOOP
04700
04800
04900 ;INTERSECTING PLANES AND SURROUNDERS AND CORNERS
05000 INTERS: EXCH P,TEM1
05100 AOBJP P,EXIT5
05200 MOVE B,(P)
05300 EXCH P,TEM1
05400 HLRE AA,11(A)
05500 HRRE BB,11(A)
05600 HLRE CC,12(A)
05700 HLRE AAA,11(B)
05800 HRRE BBB,11(B)
05900 HLRE CCC,12(B)
05950 MOVE KKK,13(B)
05975 MOVE KK,13(A)
06000
06100 MOVM X,CC
06200 MOVM Y,CCC
06300 CAML X,Y
06400 JRST [EXCH CC,CCC
06405 EXCH KK,KKK
06410 EXCH AA,AAA
06420 EXCH BB,BBB
06430 JRST .+1
06440 ]
06500 SKIPN CCC
06600 JRST LOOP
06610 ASH CC,22
06700 IDIVM CC,CCC
06710 MOVNS KKK
06720 MUL KKK,Q
06725 ASHC KKK,-22
06730 JFCL 17,.+1
06740 ADD KKK+1,KK
06800 IMUL AAA,Q
06900 IMUL BBB,Q
06910 ASH AAA,-22
06920 ASH BBB,-22
07000 SUB AA,AAA
07100 SUB BB,BBB
07200 MOVM X,AA
07300 MOVM Y,BB
07400 CAMG X,Y
07500 JRST INTERP
07600
07700 MOVN X,XL
07710 IMUL X,BB
07740 ADD X,KKK+1
07760 IDIV X,AA
07770 MOVE X1,X
07780
07790 MOVN X,YH
07800 IMUL X,BB
07830 ADD X,KKK+1
07850 IDIV X,AA
07860 MOVE X2,X
07870 MOVE Y2,YH
07880 MOVE Y1,YL
09000 JSR CLIP
09100 JRST LOOP
00100 INTERP: MOVN X,XL
00110 IMUL X,AA
00140 ADD X,KKK+1
00160 IDIV X,BB
00170 MOVE X1,X
00180
00190 MOVN X,XH
00200 IMUL X,AA
00230 ADD X,KKK+1
00250 IDIV X,BB
00260
00270 MOVE Y2,X
00280 MOVE Y1,X1
00290 MOVE X1,XL
00300 MOVE X2,XH
01300 JSR CLIP
01400 JRST LOOP
00100 DEFINE FRAM $ (A,B,C,D) {
00110 MOVE X1,X$A
00120 MOVE Y1,Y$B
00130 SUB X1,X$C
00140 SUB Y1,Y$D
00150 HRL Y1,X1
00160 HRR Y,Y$D
00170 HRL Y,X$C
00180 PUSH P,Y
00190 PUSH P,Y1
00200 ⎇
00210 FRAME: 0
00220 FRAM L,H,L,L
00230 FRAM H,H,L,H
00240 FRAM H,L,H,H
00250 FRAM L,L,H,L
00260 JRST @FRAME
00300
00400 EXIT5: EXCH P,TEM1
00500 MOVNS P ;LEFT HALF WORD APPEARS COMPLEMENTED & DECREMENTED
00600 HLLM P,INPUT6
00700 MOVEI P,INPUT6
00800 HRRM P,INPUT6
00900 JRST @PASS5
00100 ;PASS5 LINE SEGMENT CLIPPING ROUTINE
00200 CLIP: 0
00300 HRREI X,-14
00400 MOVEM X,LIMIT2#
00500 CLIP3: AOSL LIMIT2
00600 JRST @CLIP
00700 ;EXIT IF BOTH END-POINTS ARE OUTSIDE
00800 CAMG X1,XH ;BOTH ABOVE XH
00900 JRST .+3
01000 CAMLE X2,XH
01100 JRST @CLIP
01200 CAMG Y1,YH ;BOTH ABOVE YH
01300 JRST .+3
01400 CAMLE Y2,YH
01500 JRST @CLIP
01600 CAML X1,XL ;BOTH BELOW XL
01700 JRST .+3
01800 CAMGE X2,XL
01900 JRST @CLIP
02000 CAML Y1,YL ;BOTH BELOW YL
02100 JRST .+3
02200 CAMGE Y2,YL
02300 JRST @CLIP
02400
02500 CAMLE X1,XH ;IS (X1,Y1) WITHIN
02600 JRST NO1
02700 CAMLE XL,X1
02800 JRST NO1
02900 CAMLE Y1,YH
03000 JRST NO1
03100 CAMLE YL,Y1
03200 JRST NO1
03300 CAMLE X2,XH ;IS (X2,Y2) WITHIN
03400 JRST NO2
03500 CAMLE XL,X2
03600 JRST NO2
03700 CAMLE Y2,YH
03800 JRST NO2
03900 CAMLE YL,Y2
04000 JRST NO2
04100 CLIP2: SUB X2,X1 ;BOTH POINTS WITHIN; DISPLAY & EXIT.
04200 SUB Y2,Y1
04300 HRL Y1,X1
04400 HRL Y2,X2
04500 PUSH P,Y1
04600 PUSH P,Y2
04700 JRST @CLIP
04800
04900 NO2: MOVE XN,X1 ;1 IN, 2 OUT.
05000 MOVE YN,Y1
05100 JSR N2
05200 JRST CLIP2
05300
05400 NO1: CAMLE X2,XH ;IS (X2,Y2) WITHIN
05500 JRST NO3
05600 CAMLE XL,X2
05700 JRST NO3
05800 CAMLE Y2,YH
05900 JRST NO3
06000 CAMLE YL,Y2
06100 JRST NO3
06200 MOVE XM,X2 ;2 IN, 1 OUT.
06300 MOVE YM,Y2
06400 JSR M1
06500 JRST CLIP2
06600
06700 NO3: MOVE XM,X1 ;CALCULATE MIDPOINT
06800 MOVE YM,Y1
06900 ADD XM,X2
07000 ADD YM,Y2
07100 ASH XM,-1
07200 ASH YM,-1
07300 CAMLE XM,XH ;IS (XM,YM) WITHIN
07400 JRST NO4
07500 CAMLE XL,XM
07600 JRST NO4
07700 CAMLE YM,YH
07800 JRST NO4
07900 CAMLE YL,YM
08000 JRST NO4
08100 MOVE XN,XM
08200 MOVE YN,YM
08300 JSR N2
08400 JSR M1
08500 JRST CLIP2
08600
08700 NO4: CAMG X1,XH ;BOTH ABOVE XH
08800 JRST .+3
08900 CAMLE XM,XH
09000 JRST NO5
09100 CAMG Y1,YH ;BOTH ABOVE YH
09200 JRST .+3
09300 CAMLE YM,YH
09400 JRST NO5
09500 CAML X1,XL ;BOTH BELOW XL
09600 JRST .+3
09700 CAMGE XM,XL
09800 JRST NO5
09900 CAML Y1,YL ;BOTH BELOW YL
10000 JRST .+3
10100 CAMGE YM,YL
10200 JRST NO5
10300 MOVE X2,XM
10400 MOVE Y2,YM
10500 JRST CLIP3
10600 NO5: MOVE X1,XM
10700 MOVE Y1,YM
10800 JRST CLIP3
10900
00100 N2: 0 ;N IS IN, 2 IS OUT.
00200 HRREI X,-13
00300 MOVEM X,LIMIT#
00400 N2C: AOSL LIMIT
00500 JRST @N2
00600 MOVE X,XN ;MIDPOINT
00700 MOVE Y,YN
00800 ADD X,X2
00900 ADD Y,Y2
01000 ASH X,-1
01100 ASH Y,-1
01200 CAME X,XN ;EXIT ON MATCH
01300 JRST N2B
01400 CAME Y,YN
01500 JRST N2B
01600 N2A: MOVE X2,XN ;EXIT
01700 MOVE Y2,YN
01800 JRST @N2
01900 N2B: CAME X,X2
02000 JRST .+3
02100 CAMN Y,Y2
02200 JRST N2A
02300 CAMLE X,XH ;IS (X,Y) WITHIN
02400 JRST NON2
02500 CAMLE XL,X
02600 JRST NON2
02700 CAMLE Y,YH
02800 JRST NON2
02900 CAMLE YL,Y
03000 JRST NON2
03100 MOVE XN,X ;MIDPOINT WITHIN
03200 MOVE YN,Y
03300 JRST N2C
03400 NON2: MOVE X2,X ;MIDPOINT OUTSIDE
03500 MOVE Y2,Y
03600 JRST N2C
00100 M1: 0 ;M IS IN, 1 IS OUT.
00200 HRREI X,-13
00300 MOVEM X,LIMIT#
00400 M1C: AOSL LIMIT
00500 JRST @M1
00600 MOVE X,XM ;MIDPOINT
00700 MOVE Y,YM
00800 ADD X,X1
00900 ADD Y,Y1
01000 ASH X,-1
01100 ASH Y,-1
01200 CAME X,XM ;EXIT ON MATCH
01300 JRST M1B
01400 CAME Y,YM
01500 JRST M1B
01600 M1A: MOVE X1,XM ;EXIT
01700 MOVE Y1,YM
01800 JRST @M1
01900 M1B: CAME X,X1
02000 JRST .+3
02100 CAMN Y,Y1
02200 JRST M1A
02300 CAMLE X,XH ;IS (X,Y) WITHIN
02400 JRST NOM1
02500 CAMLE XL,X
02600 JRST NOM1
02700 CAMLE Y,YH
02800 JRST NOM1
02900 CAMLE YL,Y
03000 JRST NOM1
03100 MOVE XM,X ;MIDPOINT WITHIN
03200 MOVE YM,Y
03300 JRST M1C
03400 NOM1: MOVE X1,X ;MIDPOINT OUTSIDE
03500 MOVE Y1,Y
03600 JRST M1C
03700
03800 END
00100 ;OUTPUT TO ARDS & BYPASS
00200 TITLE PASS6
00300 EXTERNAL INPUT6,INPUT3,NUMTRI
00400 INTERNAL PASS6,BYPASS
00500 OPDEF OUTCHR[XWD 51040,0]
00600 ;ACCUMULATORS
00700 P←1
00800 X←2
00900 Y←3
01000 X2←4
01100 Y2←5
01200 A←6
01300 FLAG←7
01400 PASS6: 0
01500 MOVE P,INPUT6
01600 LOOP2: SETZM FLAG
01700 LOOP: AOBJP P,EXIT6
01800 OUTCHR [35] ;DOT
01900 HLRE X,(P)
02000 JSR ARDS
02100 HRRE X,(P)
02200 JSR ARDS
02300 OUTCHR [36] ;VECTOR
02400 AOBJP P,EXIT6
02500
02600 HLRE X,(P)
02700 HRRE Y,(P)
02800 MOVM A,X
02900 CAIL A,2000
03000 JSR TWOVEC
03100 MOVM A,Y
03200 CAIL A,2000
03300 JSR TWOVEC
03400 JSR ARDS
03410 MOVE X,Y
03420 JSR ARDS
03500 JUMPE FLAG,LOOP
03600 MOVE X,X2
03700 JSR ARDS
03800 MOVE X,Y2
03900 JSR ARDS
04000 JRST LOOP2
04100
04200 TWOVEC: 0
04300 SETOM FLAG
04400 MOVE X2,X
04500 MOVE Y2,Y
04600 ASH X,-1
04700 ASH Y,-1
04800 SUB X2,X
04900 SUB Y2,Y
05000 JRST @TWOVEC
05100 EXIT6: OUTCHR [15]
05200 JRST @PASS6
00100 ARDS: 0
00200 MOVM A,X
00300 ASH A,1
00400 SKIPGE X
00500 TRO A,1 ;SIGN BIT
00600 ANDI A,77
00700 IORI A,100
00800 OUTCHR A
00900 MOVM A,X
01000 ASH A,-5
01100 ANDI A,37
01200 IORI A,100
01300 OUTCHR A
01400 JRST @ARDS
00100 X1←2
00200 Y1←3
00300 X3←10
00400 Y3←11
00500 II←12
00600 A1←13
00700 A2←14
00800 A3←15
00900 BYPASS: 0 ;BYPASS OCCULT LINE ELIMINATION
01000 MOVE A1,NUMTRI
01100 MOVEI A2,INPUT6
01200 LOOP3: SKIPN A1
01300 JRST [ MOVEI INPUT6
01400 MOVEM INPUT6
01500 HLRZ A1,A2
01600 MOVNS A1
01650 SOS A1
01700 HRLM A1,INPUT6
01800 JRST @BYPASS]
01900 SOS A3,A1
02000 IMULI A3,5
02100 ADDI A3,INPUT3
02200 HLRE X1,0(A3)
02300 HRRE Y1,0(A3)
02400 HLRE X2,1(A3)
02500 HRRE Y2,1(A3)
02600 HLRE X3,2(A3)
02700 HRRE Y3,2(A3)
02800 HRRZ II,4(A3)
02900
00100 DEFINE PUTOUT $ (N,M)
00200 {
00300 PUSH A2,N-1(A3)
00400 SUB X$M,X$N
00500 SUB Y$M,Y$N
00600 HRL Y$M,X$M
00700 PUSH A2,Y$M
00710 HLRE X$M,M-1(A3)
00720 HRRE Y$M,M-1(A3)
00800 ⎇
00900
03000 TRNE II,4
03100 JRST [
03150 PUTOUT 2,3
03175 JRST .+1]
03200 TRNE II,2
03300 JRST [
03350 PUTOUT 1,3
03375 JRST .+1]
03400 TRNE II,1
03500 JRST [
03550 PUTOUT 1,2
03575 JRST .+1]
03600 JRST LOOP3
03700
04200 END
00100 TITLE DATA
00200 INTERNAL NUMTRI,TRIBLKS,TRITAB,INPUT3,INPUT6,FFLAG,INPUT5,OUTPDL
00300 INTERNAL ENDPDL,END6
00400 NUMTRI: 20
00500 TRIBLKS: 0
00600 BLOCK 400
00700 TRITAB: 0
00800 BLOCK 40
00900 INPUT3:
01000 DEFINE TRIANG (X1,Y1,Z1,X2,Y2,Z2,X3,Y3,Z3,N)
01100 {
01200 XWD X1,Y1
01300 XWD X2,Y2
01400 XWD X3,Y3
01500 XWD Z1,Z2
01600 XWD Z3,N
01700 ⎇
01800
01900 DEFINE QUAD (X1,Y1,X2,Y2,Z12,X3,Y3,X4,Y4,Z34)
02000 {
02100 TRIANG X1,Y1,Z12,X2,Y2,Z12,X3,Y3,Z34,5
02200 TRIANG X1,Y1,Z12,X3,Y3,Z34,X4,Y4,Z34,6
02300 ⎇
02400
02500 QUAD -500,-700,-500,-200, 200, 440,-200, 440,-700,200
02600 QUAD -440,-100,-440, 200, 600, 300, -40,300,-600, 100
02700 QUAD 0,100,0,500,100,440,500,440,100,100
02800 QUAD -440,400,-440,700,600,-240,700,-240,400,600
02900 QUAD 0,500,440,500,100,-240,700,-440,700,600
03000 QUAD 0,100,440,100,100,-240,400,-440,400,600
03100 QUAD 440,100,440,500,100,-240,700,-240,400,600
03200 QUAD 0,100,0,500,100,-440,700,-440,400,600
03205
03210 FFLAG: -1 ;FRAME FLAG
03215 OUTPDL: .+3
03220
03225 INPUT5: XWD 1200,INPUT3
03230 XWD -500,-500
03235 BLOCK 14000
03236 ENDPDL: 0 ↔ 0 ↔ 0 ↔ 0
03240 INPUT6: 0
03260 BLOCK 40000
03261 END6: 0 ↔ 0 ↔ 0 ↔ 0
03300 END